<template>
  <template v-if="getDataType(item)">
    <el-table-column
      v-if="!item.hide"
      :fixed="item.fixed != '' ? item.fixed : false"
      :type="item.columnType != '' ? item.columnType : undefined"
      :prop="item.prop"
      :label="item.label"
      :width="flexWidth(item, tableData)"
    >
      <template #header>
        <div
          style="display: flex; justify-content: center; align-items: center"
        >
          {{ item.label }}
          <el-icon v-if="item.order === 'ascending'"><ArrowUpBold /></el-icon>
          <el-icon v-if="item.order === 'descending'"
            ><ArrowDownBold
          /></el-icon>
        </div>
      </template>
      <template v-if="item.children.length>0">
      <template v-for="(item2, index) in item.children" :key="index"> 
         <tableColumn :item="item2" :tableData="tableData" :editKey="editKey" :flexColumnWidth="flexColumnWidth" :table-rows="tableRows" @updataTable="getTableData"></tableColumn>
      </template>
    </template>
    </el-table-column>
  </template>
  <template v-if="item.template !== null && item.editItem == null">
    <el-table-column
      v-if="!item.hide"
      :fixed="item.fixed != '' ? item.fixed : false"
      :label="item.label"
      :prop="item.prop"
      :width="flexWidth(item, tableData)"
    >
      <template #header>
        <div
          style="display: flex; justify-content: center; align-items: center"
        >
          {{ item.label }}
          <el-icon v-if="item.order === 'ascending'"><ArrowUpBold /></el-icon>
          <el-icon v-if="item.order === 'descending'"
            ><ArrowDownBold
          /></el-icon>
        </div>
      </template>
      <template #default="scope">
        <template v-for="(nodeItem, index) in item.template.nodes" :key="index">
          <component
            v-if="tableRows > 0"
            :is="getWidgetName(nodeItem.component)"
            :nodeItem="nodeItem"
            :scope="scope"
            :prop="item.prop"
            @confirmDelClick="confirmDelClick"
            @openDialog="openDialog"
            @updateTable="getTableData"
            @updateShow="updateShow(scope, $event)"
          >
          </component>
        </template>
      </template>
    </el-table-column>
  </template>
  <template v-if="item.editItem !== null && item.template == null">
    <el-table-column
      v-if="!item.hide"
      :fixed="item.fixed != '' ? item.fixed : false"
      :label="item.label"
      :prop="item.prop"
      :width="flexWidth(item, tableData)"
    >
      <template #header>
        <div
          style="display: flex; justify-content: center; align-items: center"
        >
          {{ item.label }}
          <el-icon v-if="item.order === 'ascending'"><ArrowUpBold /></el-icon>
          <el-icon v-if="item.order === 'descending'"
            ><ArrowDownBold
          /></el-icon>
        </div>
      </template>
      <template #default="scope">
        <editColumn
          v-if="tableRows > 0"
          :item="item"
          :scope="scope"
          @editData="editData(scope, item.prop, $event)"
          :key="editKey"
        >
        </editColumn>
      </template>
    </el-table-column>
  </template>
  <template v-if="item.template !== null && item.editItem !== null">
    <el-table-column
      v-if="!item.hide"
      :fixed="item.fixed != '' ? item.fixed : false"
      :label="item.label"
      :prop="item.prop"
      :width="flexWidth(item, tableData)"
    >
      <template #header>
        <div
          style="display: flex; justify-content: center; align-items: center"
        >
          {{ item.label }}
          <el-icon v-if="item.order === 'ascending'"><ArrowUpBold /></el-icon>
          <el-icon v-if="item.order === 'descending'"
            ><ArrowDownBold
          /></el-icon>
        </div>
      </template>
      <template #default="scope">
        <div v-if="!scope.row.show">
          <template
            v-for="(nodeItem, index) in item.template.nodes"
            :key="index"
          >
            <component
              v-if="tableRows > 0"
              :is="getWidgetName(nodeItem.component)"
              :nodeItem="nodeItem"
              :scope="scope"
              :prop="item.prop"
              @confirmDelClick="confirmDelClick"
              @openDialog="openDialog"
              @updateTable="getTableData"
              @updateShow="updateShow(scope, $event)"
            >
            </component>
          </template>
        </div>
        <div v-else>
          <editColumn
            v-if="tableRows > 0"
            :item="item"
            :scope="scope"
            @editData="editData(scope, item.prop, $event)"
            :key="editKey"
          ></editColumn>
        </div>
      </template>
    </el-table-column>
  </template>
</template>
<script>
//局部批量注册组件
const requireAll = require.context("./field-widget/", true, /\.vue$/);
const componentsObj = {};
let arr = [];
const modulList = requireAll.keys().map((item) => requireAll(item));
modulList.forEach(({ default: modulObj }) => {
  componentsObj[modulObj.__name] = modulObj;
  arr.push(modulObj.__name);
});
export default {
  components: componentsObj, //注册所有相关组件
  name: "tableColumn", //给组件命名
  data() {
    return {
      comList: arr,
    };
  },
};
</script>
<!-- <script>
export default {
  name: "tableColumn", //给组件命名
};
</script> -->
<script setup>
import { render, createVNode,getCurrentInstance } from "vue";
import Api from "@/api/model/system";
import { ElNotification, ElMessageBox } from "element-plus";
import {
  Plus,
  Delete,
  Edit,
  Reading,
  Minus,
  FullScreen,
  Refresh,
  Search,
  Upload,
  Printer,
  Setting,
  SetUp,
  ArrowUpBold,
  ArrowDownBold
} from "@element-plus/icons-vue";
import tsLayer from "@/utils/useDialog";
import "./field-widget/index";
import editColumn from "./column-widget/editColumn.vue";
import columnSetting from "./column-widget/columnSetting.vue";
const emit = defineEmits(["updateTable"]);
const instance = getCurrentInstance();
const props = defineProps({
  tableData: { type: Array, default: () => [] },
  item: { type: Object, default: () => {} },
  editKey: { type: String, default: "" },
  flexColumnWidth: { type: String, default: "" },
  tableRows: { type: String, default: "" },
});
const getWidgetName = (widget) => {
  return widget + "-widget";
};
const getDataType = (item) => {
  let dataType = false;
  if (item.columnType != "") {
    dataType = true;
  } else if (
    item.template == null &&
    item.editItem == null
  ) {
    dataType = true;
  }
  return dataType;
};
/**
 * 编辑取消保存按钮的相关操作
 */
const updateShow = (prop, val) => {
  prop.row.show = val;
  if (val == false) {
    getTableData();
  }
};
/**修改行数据 */
const editData = (scope, prop, params) => {
  if (params.code) {
    scope.row[params.code] = params.value;
  } else {
    scope.row[prop] = params.value;
  }
};
const getTableData = () => {
  emit("updateTable");
};
const confirmDelClick = async (url, id) => {
  const res = await Api.systemDelete.post(url, id);
  if (res.code == 200) {
    ElNotification.success({ title: "", message: "成功！", duration: 2000 });
    if (res.optType == "exportFile") {
      window.open(res.data);
    }
    getTableData();
  } else {
    ElNotification.error({ title: "失败", message: res.msg });
  }
};
const openDialog = (item, paramsData) => {
  const box = document.querySelector(".dialog");
  render(null, box);
  let path;
  if (paramsData.url !== "" && paramsData.url !== undefined) {
    path = paramsData.url;
  } else {
    path = item.url;
  }
  import(`@/views${path}`).then((res) => {
    const form = createVNode(res.default, {
      paramsData,
      onUpdatetable(val) {
        render(null, box);
        if (val == true) {
          getTableData();
        }
      },
      onOpenDialog(val) {
        console.log(val);
      },
    });
    tsLayer.open({
      title: item.title,
      width: item.width,
      fullScreen: item.fullscreen,
      appContext: instance.appContext,
      box: box,
      content: form,
    });
  });
};
const flexWidth = (item, tableData, num = 0) => {
  if (item.width) {
      return item.width;
    }
  if (
    item.flexColumnWidth == false ||
    tableData.length == 0 ||
    props.flexColumnWidth == false
  ) {
    // 表格没数据不做处理
    if (item.width) {
      return item.width;
    }
    return;
  }
  let flexWidth = 0; // 初始化表格列宽
  let columnContent = ""; // 占位最宽的内容
  let canvas = document.createElement("canvas");
  let context = canvas.getContext("2d");
  context.font = "14px Microsoft YaHei";
  if (item.prop === "" && item.title) {
    // 标题长内容少的，取标题的值,
    columnContent = item.title;
  } else {
    // 获取该列中占位最宽的内容
    let index = 0;
    for (let i = 0; i < tableData.length; i++) {
      const now_temp = tableData[i][item.prop] + "";
      const max_temp = tableData[index][item.prop] + "";
      const now_temp_w = context.measureText(now_temp).width;
      const max_temp_w = context.measureText(max_temp).width;
      if (now_temp_w > max_temp_w) {
        index = i;
      }
    }
    columnContent = tableData[index][item.prop];

    // 比较占位最宽的值跟标题、标题为空的留出四个位置
    const column_w = context.measureText(columnContent).width;
    const title_w = context.measureText(item.title).width;
    if (column_w < title_w) {
      columnContent = item.title || "占位符呀";
    }
  }
  // 计算最宽内容的列宽
  let width = context.measureText(columnContent);
  flexWidth = width.width + 40 + num;
  return flexWidth;
};
</script>